home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 7113 < prev    next >
Encoding:
Text File  |  1996-08-05  |  4.6 KB  |  152 lines

  1. Path: rain.fr!world-net!usenet
  2. From: Frederic LACHASSE <lachass@worldnet.fr>
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: design problem
  5. Date: Tue, 20 Feb 1996 19:40:03 +0000
  6. Organization: World-Net information exchange, Internet provider.
  7. Message-ID: <VA.00000049.00372a88@fred>
  8. References: <DMMwLp.Awv@emr1.emr.ca>
  9. Reply-To: lachass@worldnet.fr
  10. NNTP-Posting-Host: pm9-007.sct.fr
  11. X-Newsreader: Virtual Access by Ashmount Research Ltd, http://www.ashmount.com
  12.  
  13. In article <DMMwLp.Awv@emr1.emr.ca>, jagrant@emr1.emr.ca (John Grant) wrote:
  14. > Problem
  15. > -------
  16. > I have several file types:  A,B,C...
  17. > Each one has an Open(), Close(), Draw() & Size() function, the nature
  18. > of which is specific to the file type, but which is common to all file types.
  19. > Each file type has specific functions as well, i.e. GetAStuff() for 'A' files.
  20. > Implementation
  21. > --------------
  22. > I want to create a class I can use for each file, regardless of type.  Later,
  23. > I will want to put a bunch of these into a container, i.e. an array of some
  24. > sort:
  25. >  cMYFILE *f1 = new cMYFILE("xxx.a"); //file type 'A'
  26. >  cMYFILE *f2 = new cMYFILE("yyy.b"); //file type 'B'
  27. >  ...
  28. > I need to call the 'generic' functions which are common to all file types:
  29. > Open(), Draw(), Size()
  30. > However, I also need to be able to call functions which are specific to the
  31. > file type.  Presumably, I must first inspect the object to determine the
  32. > file type:
  33. >  if(f1->Type()=='a') f1->GetAStuff();
  34. >  if(f1->Type()=='b') f1->GetBStuff();
  35. > I haven't got a clue how to design these classes or how many I need.  I started
  36. > out with a base class:
  37. >  class cMYFILE{
  38. >    public: cMYFILE(char *name);
  39. >     ~cMYFILE();
  40. >     virtual int Open(void) = 0;
  41. >     virtual int Draw(void) = 0;
  42. >     virtual int Size(void) = 0;
  43. >     virtual char Type(void) = 0;
  44. >  };
  45. > and then decided I needed to derive an A,B,C class from cMYFILE in order
  46. > to implement the generic virtual functions and add in other file-specific
  47. > functions :
  48. >  class cMYFILE_A:public cMYFILE{
  49. >    public:  int Open(void);
  50. >      int Draw(void);
  51. >      int Size(void);
  52. >      int Type(void);
  53. >      int GetAStuff(void);
  54. >  };
  55. >  class cMYFILE_B:public cMYFILE{
  56. >    public:  int Open(void);
  57. >      int Draw(void);
  58. >      int Size(void);
  59. >      int Type(void);
  60. >      int GetBStuff(void);
  61. >  };
  62. > Then I got confused. I don't know which functions should be virtual, 
  63. > which functions should be pure virtual and what stuff should be in the 
  64. > base class and what stuff should be in the derived classes. I'm just 
  65. > confused.
  66.  
  67. You want to access AStuff and BStuff from the base, so the base must be aware 
  68. that AStuff and BStuff exists. Your classes should be:
  69.  
  70. class cMYFILE
  71. {
  72. public:
  73.   cMYFILE(const char *name);
  74.   virtual ~cMYFILE(); /*1*/ /*2*/
  75.   virtual int Open()=0;
  76.   virtual int Draw()=0;
  77.   virtual int Size() const=0; /*3*/
  78.   virtual char Type() const=0;
  79.   virtual GetAStuff() const { return NOT_IMPLEMENTED; } /*4*/
  80.   virtual GetBStuff() const { return NOT_IMPLEMENTED; }
  81. };
  82.  
  83. class cMYFILE_A:public cMYFILE
  84. {
  85. public:
  86.   cMYFILE_A(const char *name);
  87.   int Open();
  88.   int Draw();
  89.   int Size() const;
  90.   int Type() const;
  91.   int GetAStuff() const;
  92. };
  93.  
  94. class cMYFILE_B:public cMYFILE
  95. {
  96. public:
  97.   cMYFILE_B(const char *name);
  98.   int Open();
  99.   int Draw();
  100.   int Size() const;
  101.   int Type() const;
  102.   int GetBStuff() const;
  103. };
  104.  
  105. Notes:
  106.  (1) You'll probably need a virtual destructor: containers are used to free 
  107. objects store in them, so delete from base pointer to derived objects.
  108.  (2) func(void) prototype is obsolete in C++, use func().
  109.  (3) It's best to use const whenever possible. (May be I haven't place them at 
  110. the right place)
  111.  (4) These are not pure virtual. That's why I do not have to define them in 
  112. derived classes that don't implement the specific stuff.
  113.  
  114. > A related problem, which I haven't dealt with is to create a container
  115. > class which will hold a list of these files, so I can do:
  116. >  nfile=filelist->nfile();
  117. >  for(i=0;i<nfile;i++){
  118. >    filelist->Open(i);
  119. >    filelist->Draw(i);
  120. >    filelist->Close(i);
  121. >  }
  122.  
  123. Containers for polymorphic classes just stores pointers to the base class and 
  124. manipulate the objects through these pointers. A common feature (but not 
  125. mandatory) of objects stored in containers is the ability to copy (or clone) 
  126. themselves. That is achieved by a virtual member function that must be redefined 
  127. for every sub-class:
  128.  
  129. class Object : public Base
  130. {
  131. public:
  132.   Object(const Object &); // copy constructor
  133.   virtual Object *clone() const { return new Object(*this); }
  134. };
  135.  
  136. I hope that'll help you clarify OO programming in C++.
  137.  
  138.  Frederic LACHASSE (ECP 86)
  139.  CompuServe: 100530,2005
  140.  Internet: lachass@worldnet.fr
  141.  
  142.